import static java.lang.Math.PI;
import static java.lang.Math.cos;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;

import util.MyMath;
public class Wall extends WorldObject
{
	double x1, y1, x2, y2;
	Point[] vertices;
	double thickness;
	double angle, slope;
	//distance helper
	double distance;
	boolean edgesReady = false;
	
	Point testPoint = new Point();
	Point xPoint = new Point(), yPoint = new Point();
	WallEdge[] edges = new WallEdge[4];
	public Wall()
	{
	}
	public Wall(double x1, double y1, double x2, double y2, double thickness)
	{
		if(x1 > x2)//switch points
		{
			double tempX1 = x1;
			x1 = x2;
			x2 = tempX1;
			double tempY1 = y1;
			y1 = y2;
			y2 = tempY1;
		}
		this.x1 = x1;
		this.y1 = y1;
		this.x2 = x2;
		this.y2 = y2;
		this.thickness = thickness;
		vertices = new Point[4];
		updatePoints();
	}
	public void updateAngle()
	{
		angle = Math.atan((y2 - y1) / (x2 - x1));
		if(y2 < y1)
			angle *= -1;
		if(y1 < y2)
			angle = PI - angle;
		System.out.println(angle / PI);
	}
	public void updatePoints()
	{
		updateAngle();
		//Bottom left
		vertices[0] = new Point((int)(x1 - thickness / 2 * cos(PI / 2 - angle)), (int) (y1 - thickness / 2 * Math.sin(PI / 2 - angle)));
		//Bottom right
		vertices[1] = new Point((int)(x2 - thickness / 2 * cos(PI / 2 - angle)), (int) (y2 - thickness / 2 * Math.sin(PI / 2 - angle)));
		//Top right
		vertices[2] = new Point((int)(x2 + thickness / 2 * cos(PI / 2 - angle)), (int) (y2 + thickness / 2 * Math.sin(PI / 2 - angle)));
		//Top left
		vertices[3] = new Point((int)(x1 + thickness / 2 * cos(PI / 2 - angle)), (int) (y1 + thickness / 2 * Math.sin(PI / 2 - angle)));
		slope = (y2-y1) / (x2-x1);

		updateWalls();
	}
	public void translate(double x, double y)
	{
		x1 += x;
		x2 += x;
		y1 += y;
		y2 += y;
		updatePoints();
	}
	public Graphics2D paintObject(Graphics2D g2)
	{
		g2.setColor(Color.BLACK);
		if(edgesReady)
		{
			for(WallEdge edge: edges)
				edge.paintEdge(g2);
		}
		g2.drawString("3", (int) vertices[3].getX(), (int) vertices[3].getY());
		g2.drawString("2", (int) vertices[2].getX(), (int) vertices[2].getY());
		g2.drawString("0", (int) vertices[0].getX(), (int) vertices[0].getY());
		g2.drawString("1", (int) vertices[1].getX(), (int) vertices[1].getY());
//		g2.draw(new Ellipse2D.Double(getPointWithY(150).getX(), 150, 3, 3));
		//g2.draw(new Ellipse2D.Double(xPoint.getX(), xPoint.getY(), 3, 3));
		//g2.draw(new Ellipse2D.Double(yPoint.getX(), yPoint.getY(), 3, 3));
		//g2.draw(new Ellipse2D.Double(x1, y1, 3, 3));
		//g2.draw(new Ellipse2D.Double(x2, y2, 3, 3));
		
		return g2;
	}
	private Point getPointWithX(double x)
	{
		double yNew = y1 + (x - x1)*slope;
		Point newPoint = new Point();
		newPoint.setLocation(x, yNew);
		return newPoint;
	}
	private Point getPointWithY(double y)
	{
		double xNew = x1 + (y - y1) / slope;
		Point newPoint = new Point();
		newPoint.setLocation(xNew, y);
		return newPoint;
	} 
	private double distance(Point a, Point b)
	{
		return Math.pow(Math.pow(b.getX() - a.getX(), 2) + Math.pow(b.getY() - a.getY(), 2), .5);
	}
	public boolean checkParticleCollision(MyObject obj)
	{
		boolean collided = false;
		for(WallEdge edge: edges)
			if(edge.checkCollision(obj))
			{
				collided = true;
			}
		return collided;
	}
	private int compare(String component, double value, int vertexI)
	{
		Point vertex = vertices[vertexI];
		if(component.equals("x"))
		{
		}
		return 0;
	}
	private void updateWalls()
	{
		edges[0] = new WallEdge(vertices[0], vertices[1]);
		edges[1] = new WallEdge(vertices[1], vertices[2]);
		edges[2] = new WallEdge(vertices[2], vertices[3]);
		edges[3] = new WallEdge(vertices[3], vertices[0]);
		edgesReady = true;
	}
	private Point intersectLines(double m1, double c1, double m2, double c2)
	{
		Point point = new Point();
		double x = (c1 - c2) / (m2 - m1);
		double y = x * m1 + c1;
		point.setLocation(x, y);
		return point;
	}
	public class WallEdge
	{
		Point closestPoint = new Point();
		double slope, constant, angle;
		Point a, b;
		public WallEdge(Point a, Point b)
		{
			this.a = a;
			this.b = b;
			slope = (b.getY() - a.getY()) / (b.getX() - a.getX());
			constant = a.getY() - a.getX() * slope;
			angle = MyMath.aTan((b.getY() - a.getY()), (b.getX() - a.getX()));
		}
		public WallEdge()
		{
			
		}
		void paintEdge(Graphics2D g2)
		{
			g2.drawLine((int) a.getX(),(int) a.getY(),(int) b.getX(),(int) b.getY());
			//g2.draw(new Ellipse2D.Double(closestPoint.getX(), closestPoint.getY(), 3, 3));
		}
		boolean checkCollision(MyObject obj)
		{
			double perpSlope = -Math.pow(slope, -1);
			double objConstant = obj.y - obj.x * perpSlope;
			closestPoint = intersectLines(slope, constant, perpSlope, objConstant);
			Point objPoint = new Point();
			objPoint.setLocation(obj.x, obj.y);
			if(isPointValid(closestPoint) && distance(closestPoint, objPoint) < obj.radius && (obj.lastCollision == null || !obj.lastCollision.equals(this)))
			{
				double[] vector1 = obj.getVVector();
				double alpha = PI - vector1[1] - angle;
				double[] vector2 = {vector1[0], PI + alpha * 2};
				obj.setVFromVector(vector2);
				System.out.println(vector1[1]);
				obj.lastCollision = this;
				return true;
			}
			return false;
		}
		public boolean equals(Wall.WallEdge edge)
		{
			if(this.a.equals(edge.a) && this.b.equals(edge.b))
				return true;
			return false;
		}
		private boolean isPointValid(Point p)
		{
			//check X and Y
			if((p.getX() <= a.getX() && p.getX() >= b.getX()) || (p.getX() >= a.getX() && p.getX() <= b.getX()))
				if((p.getY() <= a.getY() && p.getY() >= b.getY()) || (p.getY() >= a.getY() && p.getY() <= b.getY()))
					return true;
			return false;
		}
	}
	
}
